/*
 * Copyright (c) 2001, 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.perforce.core.resources;

import net.sourceforge.perforce.core.internal.sync.SyncStatus;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.core.sync.ILocalSyncElement;
import org.eclipse.team.core.sync.IRemoteResource;
import org.eclipse.team.core.sync.IRemoteSyncElement;
import org.eclipse.team.core.sync.RemoteSyncElement;

/**
  * @version $Revision: 18 $
  * @author  <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class PerforceRemoteSyncElement extends RemoteSyncElement
{
	// --------------------------------------------------------------------------- Private Variables

	/** Flag indicating whether base should be ignored. */	
	private boolean ignoreBaseTree;
	/** Force three way compare ? */
	private boolean forceThreeway;
	/** Reference to the local resource. */
	private LocalResource local;
	/** Reference to the remote stored base version. */
	private IRemoteResource base;
	/** Reference to the remote version. */
	private IRemoteResource remote;
	/** SyncStatus info. */
	private SyncStatus[] syncStatus;

	// ------------------------------------------------------------------------- Public Constructors

	/** Constructor for PerforceRemoteSyncElement.
	  * 
	  * @param ignoreBaseTree ignore the base?
	  * @param local the local resource.
	  * @param base the base resource.
	  * @param remote the remote resource.
	  * @param data generic data.
	  */
	public PerforceRemoteSyncElement(boolean ignoreBaseTree, LocalResource local, 
		IRemoteResource base, IRemoteResource remote, Object data) 
	{
		this.ignoreBaseTree = ignoreBaseTree;
		this.local = local;
		if (!local.toResource().exists())
		{
			forceThreeway = true;
			this.base = null;
		}
		else
		{
			this.base = base;
		}
		
		this.remote = remote;
		this.syncStatus = (SyncStatus[]) data;
	}

	// ---------------------------------------------------------- Public Methods (RemoteSyncElement)

	/** @see RemoteSyncElement#create(
	  * 	boolean, IResource, IRemoteResource, IRemoteResource, Object)
	  */
	public IRemoteSyncElement create(boolean ignoreBaseTree, IResource local, IRemoteResource base, 
		IRemoteResource remote, Object data)
	{
		return new PerforceRemoteSyncElement(ignoreBaseTree, 
			LocalResource.createFromResource(local), base, remote, data);
	}

	/** @see IRemoteSyncElement#getRemote() */
	public IRemoteResource getRemote()
	{
		return remote;
	}

	/** @see IRemoteSyncElement#ignoreBaseTree() */
	public boolean ignoreBaseTree()
	{
		return ignoreBaseTree;
	}

	/** @see IRemoteSyncElement#isOutOfDate() */
	public boolean isOutOfDate()
	{
		return local.isOutOfDate();
	}

	/** @see LocalSyncElement#create(IResource, IRemoteResource, Object) */
	public ILocalSyncElement create(IResource local, IRemoteResource base, Object data)
	{
		return null;
	}

	/** @see ILocalSyncElement#getBase() */
	public IRemoteResource getBase()
	{
		return base;
	}

	/** @see LocalSyncElement#getData() */
	protected Object getData()
	{
		return syncStatus;
	}

	/** @see ILocalSyncElement#getLocal() */
	public IResource getLocal()
	{
		return local.toResource();
	}

	/** @see ILocalSyncElement#hasRemote() */
	public boolean hasRemote()
	{
		return local.hasRemote();
	}

	/** @see ILocalSyncElement#isCheckedOut() */
	public boolean isCheckedOut()
	{
		return local.isCheckedOut();
	}

	/** @see ILocalSyncElement#isDirty() */
	public boolean isDirty()
	{
		return local.isDirty();
	}

	/** @see LocalSyncElement#isIgnored(IResource) */
	protected boolean isIgnored(IResource resource)
	{		
		for (int i = 0; i < syncStatus.length; i++)
		{
			if (syncStatus[i].getFilename().startsWith(resource.getLocation().toOSString()))
			{
				return false;
			}
		}		
		
		return true;
	}
	
	/** @see ILocalSyncElement#getSyncKind(int, IProgressMonitor) */
	public int getSyncKind(int granularity, IProgressMonitor progress)
	{
		IResource resource = local.toResource();
		if (resource.getType() == IResource.FILE)
		{
			String filename = resource.getLocation().toOSString();
			for (int i = 0, length = syncStatus.length; i < length; i++)
			{
				if (syncStatus[i].getFilename().equals(filename) &&
				    syncStatus[i].isConflicting())
				{
					return CONFLICTING | CHANGE;
				}
			}
		}		
		int result = super.getSyncKind(granularity, progress);
	
		if (result == IN_SYNC && local.isOutOfDate())
		{
			return INCOMING;
		}
		else
		{
			return result;
		}
	}
	
	/** @see IRemoteSyncElement#isThreeWay() */
	public boolean isThreeWay()
	{
		return forceThreeway ? true : base != null;
	}

	// --------------------------------------------------------------------------- Protected Methods
	
	/** @see RemoteSyncElement#timestampEquals(IRemoteResource, IRemoteResource) */
	protected boolean timestampEquals(IRemoteResource e1, IRemoteResource e2) 
	{
		return false;
	}

	/** @see RemoteSyncElement#timestampEquals(IResource, IRemoteResource) */
	protected boolean timestampEquals(IResource e1, IRemoteResource e2) 
	{
		return false;
	}
}
